// ==UserScript==
// @name         获取鼠标指定元素信息
// @namespace    http://tampermonkey.net/
// @version      2025-03-09
// @description  try to take over the world!
// @author       You
// @match        http://*/*
// @match        https://*/*
// @icon         http://wuweijun.fun/favicon.ico
// @grant        none
// ==/UserScript==

(function () {
  // 'use strict';

  // 定义一个CSS类，用于鼠标悬停时的显眼样式
  const highlightClass = 'highlight_gaoliang';

  // 创建一个<style>元素，并添加到<head>中，定义highlight类的样式
  const style = document.createElement('style');
  style.textContent = `
.${highlightClass} {
    box-shadow: 0 0 50px rgba(180, 77, 149, 0.5);
    outline: 4px outset rgba(182, 91, 170, 0.5);
    z-index: 1; /* 提升层级 */
}
`;
  document.head.appendChild(style);

  // 创建用于启动功能的按钮
  const opendiv = document.createElement('div');
  opendiv.style = "position: fixed; bottom: 0; left: 0; width: 25px; height: 25px; background-color: #d9bcf6; display: flex ; align-items: center; justify-content: center; cursor: pointer; border-radius: 0px 82px 20px 0px;z-index: 99999999;";
  opendiv.innerHTML = '🌂'
  opendiv.addEventListener('click', function () { startTo(); })
  document.body.appendChild(opendiv);

  // 获取鼠标当前元素信息，并设置元素显眼样式
  function startElementTracker() {
      let currentElement = null;

      // 获取元素及其父元素的信息
      function getElementInfo(element) {
          const info = {};
          // info.element = element;
          info.tagName = element.tagName.toLowerCase();
          info.className = element.className.trim().split(/\s+/);
          info.id = element.id;
          // info.parentInfo = element.parentElement ? getElementInfo(element.parentElement) : null; // 获取父辈元素信息
          info.innerText = element.innerText;
          // 获取所有属性
          info.attributes = {};
          Array.from(element.attributes).forEach(attr => {
              info.attributes[attr.name] = attr.value;
          });
          // 获取所有样式
          info.styles = getCustomStyles(element);
          return info;
      }

      // 获取指定元素中所有由人为设置的样式（即非默认样式）。通过比较元素的计算样式与其父元素的计算样式来实现
      function getCustomStyles(element) {
          const computedStyles = window.getComputedStyle(element);
          const parentComputedStyles = window.getComputedStyle(element.parentElement);
          let customStyles = [];
          for (let i = 0; i < computedStyles.length; i++) {
              const property = computedStyles[i];
              const value = computedStyles.getPropertyValue(property);
              const parentValue = parentComputedStyles.getPropertyValue(property);

              if (value !== parentValue) {
                  customStyles.push(`${property}: ${value};`);
              }
          }
          return customStyles;
      }

      // 鼠标移动事件监听器
      function onMouseMove(event) {
          // 获取鼠标位置下的元素
          const element = document.elementFromPoint(event.clientX, event.clientY);

          // 如果当前有选中的元素，并且不是鼠标移动到的新元素，则移除高亮样式
          if (currentElement && currentElement !== element) {
              currentElement.classList.remove(highlightClass);
          }

          // 更新当前选中的元素，并添加高亮样式
          currentElement = element;
          if (currentElement) {
              currentElement.classList.add(highlightClass);

              // 打印或处理元素信息
              debounceMain(currentElement)
          }
      }

      // 使用防抖，避免高频率的获取元素及其父元素的信息
      let debounceMain = debounce(function () {
          const elementInfo = getElementInfo(currentElement);
          copyText(elementInfo.innerText);
          MousemoveElement.textarea.innerHTML = JSON.stringify(elementInfo, null, 4);
      }, 50)

      // 鼠标离开文档或窗口时移除高亮样式（可选，但推荐）
      function onMouseLeaveDocument(event) {
          if (currentElement) {
              currentElement.classList.remove(highlightClass);
              currentElement = null; // 重置当前元素
          }
      }

      // 使用鼠标右键，关闭元素追踪功能
      function onContextmenu(event) {
          event.preventDefault();// 阻止默认的右键菜单
          stopElementTracker();
      }


      // 添加事件监听器
      document.addEventListener('mousemove', onMouseMove);
      document.addEventListener('mouseleave', onMouseLeaveDocument);
      window.addEventListener('blur', onMouseLeaveDocument); // 处理窗口失去焦点的情况，如切换到其他应用
      document.addEventListener('contextmenu', onContextmenu); // 选择你想要监听右键事件的元素，这里以整个文档为例

      // 返回一个函数来停止监听和清理
      function stopElementTracker() {
          document.removeEventListener('mousemove', onMouseMove);
          document.removeEventListener('mouseleave', onMouseLeaveDocument);
          window.removeEventListener('blur', onMouseLeaveDocument);
          document.removeEventListener('contextmenu', onContextmenu);
          if (currentElement) {
              currentElement.classList.remove(highlightClass);
              currentElement = null; // 重置当前元素
          }
          draggableDiv.style.pointerEvents = 'auto';
          draggableDiv.style.opacity = 1;
          console.log('Element tracker stopped.');
      };


      return stopElementTracker;
  }


  // 创建移动div
  let draggableDiv = null;
  function createMousemoveElement() {
      // Create the draggable div element
      draggableDiv = document.createElement('div');
      draggableDiv.id = 'draggableDiv';
      draggableDiv.style = 'min-width: 300px; max-width: 700px; max-height: 500px; border: 1px solid #000; position: fixed; top: 0; background-color: #f9f9f9; z-index: 9999999; overflow: hidden;display: flex ; flex-direction: column; opacity: 0.5;pointer-events: none;';
      function remove() { draggableDiv.remove(); draggableDiv = null; } // 移除移动div

      const mousemoveDiv = document.createElement('div');
      mousemoveDiv.style = 'width: 100%; height: 30px; background-color: rgb(235 235 235);display: flex ; justify-content: space-between; align-items: center;';
      mousemoveDiv.innerHTML = '鼠标右键取消定位元素|点击移动|已复制文本';

      const spanDiv = document.createElement('div');
      spanDiv.style = 'display: flex;';

      const span_1 = document.createElement('span');
      span_1.style = 'font-size: 20px; line-height: 27px; height: 30px; hei`30px: ; width: 30px; text-align: center; background-color: #d9bcf6; color: white;';
      span_1.innerHTML = '🌂';
      span_1.addEventListener('click', function () { startTo(); });

      const span_ = document.createElement('span');
      span_.style = 'font-size: 28px; line-height: 22px; height: 30px; hei`30px: ; width: 30px; text-align: center; background-color: #976d6d; color: white;';
      span_.innerHTML = 'x';
      span_.addEventListener('click', remove);
      spanDiv.appendChild(span_1);
      spanDiv.appendChild(span_);
      mousemoveDiv.appendChild(spanDiv);
      draggableDiv.appendChild(mousemoveDiv);

      // Create a textarea element and append it to the draggable div
      const textarea = document.createElement('pre');
      textarea.setAttribute('contenteditable', !0); // 解除浏览器限制，使元素可以编辑。
      textarea.style = 'max-width: 100%; height: 100%; padding: 5px; margin: 8px; white-space: pre-wrap;overflow-y: scroll;font-size: 17px;';
      draggableDiv.appendChild(textarea);

      // Append the draggable div to the body
      document.body.appendChild(draggableDiv);

      let offsetX, offsetY, isDragging = false;

      // Function to handle mouse down event
      const onMouseDown = (e) => {
          offsetX = e.clientX - draggableDiv.getBoundingClientRect().left;
          offsetY = e.clientY - draggableDiv.getBoundingClientRect().top;
          isDragging = true;
          document.addEventListener('mousemove', onMouseMove);
          document.addEventListener('mouseup', onMouseUp);
      };

      // Function to handle mouse move event
      const onMouseMove = (e) => {
          if (isDragging) {
              draggableDiv.style.left = `${e.clientX - offsetX}px`;
              draggableDiv.style.top = `${e.clientY - offsetY}px`;
          }
      };

      // Function to handle mouse up event
      const onMouseUp = () => {
          isDragging = false;
          document.removeEventListener('mousemove', onMouseMove);
          document.removeEventListener('mouseup', onMouseUp);
      };

      // Attach event listeners to the draggable div
      mousemoveDiv.addEventListener('mousedown', onMouseDown);

      return { textarea, draggableDiv, remove };
  }

  // 复制文本内容
  function copyText(text) {
      // let inputDom = document.createElement('input');  // 创建一个input元素
      let inputDom = document.createElement('textarea');  // 创建一个input元素
      inputDom.setAttribute('readonly', 'readonly'); // 防止手机上弹出软键盘
      inputDom.value = text; // 给input元素赋值
      document.body.appendChild(inputDom); // 添加到body
      inputDom.select(); //选中input元素的内容
      document.execCommand('Copy'); // 执行浏览器复制命令
      inputDom.style.display = 'none';
      inputDom.remove(); // 移除input元素
  }

  // 解除页面限制
  function jc() {
      !function () {
          var t = function (t) {
              t.stopPropagation(),
                  t.stopImmediatePropagation && t.stopImmediatePropagation()
          };
          ["copy", "selectstart"].forEach(function (e) {
              document.documentElement.addEventListener(e, t, {
                  capture: !0
              })
          })
      }();
  }

  // ------------------------防抖---------------------------
  function debounce(o, n) {
      var r;
      return function () {
          var t = this
          , e = arguments;
          clearTimeout(r),
              r = setTimeout(function () {
              o.apply(t, e)
          }, n)
      }
  }

  // 开始-功能
  let stopTracking, MousemoveElement;
  function startTo() {
      if (!draggableDiv) MousemoveElement = createMousemoveElement(), jc();
      stopTracking = startElementTracker();
      draggableDiv.style.pointerEvents = 'none';
      draggableDiv.style.opacity = '0.38';
  }

  // 当你想要停止追踪时，调用stopTracking函数
  // stopTracking();

})();


// document.addEventListener('DOMContentLoaded', (event) => { });